Solving WSL 2 Docker File Permission Issues
TLDR
- Core Issue: Docker containers in WSL 2 create files with
rootprivileges, causing local users (such as VS Code) to be unable to edit them due to insufficient permissions. - Not Recommended: Changing the default WSL user to
root. This causes the system to lose permission isolation and poses a high security risk. - Recommended Approach (1): Use the Dev Containers feature in VS Code to resolve permission and environment consistency issues through a containerized development environment.
- Recommended Approach (2): If integration with an existing
docker-composeis required, create a dedicatedvscode-editorcontainer and mount the working directory, usingremoteUser: rootto resolve editing permissions. - Key Advice: When using
docker-outside-of-docker, it is recommended to prioritize Named Volumes to avoid path resolution and permission hell associated with Bind Mounts across operating systems.
Causes of Permission Hell
When you encounter this issue: When you start services using Docker Compose in a WSL 2 environment, and the service creates files in a Bind Mount directory as root.
Because the root user inside the Docker container and the regular user (e.g., wing) outside of WSL are treated as different entities in the Linux permission system, external editors (like VS Code) trigger Permission Denied errors when attempting to read or write these files.
Risks of the "Brute Force" Solution
When you encounter this issue: When developers choose to modify /etc/wsl.conf to change the default user to root in order to quickly resolve permission obstacles.
WARNING
This is an extremely unsafe practice. Changing the default user to root gives all operations within WSL root privileges. If a malicious script is accidentally executed or an operation error occurs (e.g., rm -rf /), the consequences could be catastrophic. Please do not imitate this in production or critical work environments.
Dev Containers: An Elegant Development Environment
When you encounter this issue: When you want to resolve cross-environment file access and development tool configuration issues while keeping the system secure.
Dev Containers allow you to package the development environment into a container and automatically handle UID mapping. For root files generated by Docker Compose, you can ensure the editor has sufficient permissions by setting remoteUser: "root".
Practical Setup Steps
- Initialization: Press
F1in the project directory and select Dev Containers: Add Dev Container Configuration Files.... - Select Definition: Choose a suitable environment (e.g.,
Ubuntu) and ensure theDocker (outside of Docker)feature is checked. - Configure
devcontainer.json: If using Bind Mount, you must enableremoteUserin the configuration file:json{ "image": "mcr.microsoft.com/devcontainers/base:noble", "features": { "ghcr.io/devcontainers/features/docker-outside-of-docker:1": { "installDockerBuildx": true, "installDockerComposeSwitch": true, "version": "latest", "dockerDashComposeVersion": "v2" } }, "remoteUser": "root" } - Reload: Press
F1and select Dev Containers: Reopen in Container to enter the environment.
TIP
Changes to devcontainer.json only take effect after a Rebuild. If the rebuild option cannot be found in the command palette, you can execute Developer: Reload Window to reconnect.
Alternative: Integration with Docker Compose
When you encounter this issue: When you do not want to maintain a .devcontainer folder for every project, or you want the development tool container to share the network with official services.
You can add a dedicated editor container to compose.yml (or compose.override.yml):
services:
vscode-editor:
image: mcr.microsoft.com/devcontainers/base:ubuntu-24.04
container_name: vscode-editor
command: sleep infinity
user: root
volumes:
- ./:/workspace
working_dir: /workspaceAfter starting, connect to vscode-editor via the Dev Containers: Attach to Running Container... command, and set remoteUser to root in that container's configuration file to seamlessly edit all files within the container.
TIP
If you do not want to pollute the official compose.yml, it is recommended to move the above configuration to compose.override.yml. Docker Compose will automatically merge the settings upon startup.
Change Log
- 2026-01-19 Initial document created.
- 2026-01-22 Added another approach for integrating Dev Containers into Docker Compose.
- 2026-02-04 Added recommendations regarding the use of
compose.override.yml.
